Skip to content

feat(config): exporter plugin loading via entry points for declarative config#5128

Draft
MikeGoldsmith wants to merge 2 commits intoopen-telemetry:mainfrom
MikeGoldsmith:mike/config-exporter-plugin-loading
Draft

feat(config): exporter plugin loading via entry points for declarative config#5128
MikeGoldsmith wants to merge 2 commits intoopen-telemetry:mainfrom
MikeGoldsmith:mike/config-exporter-plugin-loading

Conversation

@MikeGoldsmith
Copy link
Copy Markdown
Member

@MikeGoldsmith MikeGoldsmith commented Apr 20, 2026

Description

Extends exporter support in declarative file configuration to handle custom (plugin) exporters across all three signals, matching the spec's PluginComponentProvider mechanism.

Solution

Each signal's factory function now has an exporter registry:

Signal Registry Entry point group
Traces _SPAN_EXPORTER_REGISTRY opentelemetry_traces_exporter
Metrics _METRIC_EXPORTER_REGISTRY opentelemetry_metrics_exporter
Logs _LOG_EXPORTER_REGISTRY opentelemetry_logs_exporter

Known names (otlp_http, otlp_grpc, console) route to existing typed factory functions. Unknown names fall back to load_entry_point().

The generated models are unchanged. Python dataclasses don't enforce field types at runtime, so parent fields like BatchSpanProcessor.exporter naturally accept raw dicts (from the YAML loader) alongside typed instances. This preserves unknown plugin names as dict keys without diverging from codegen.

_parse_headers in _common.py is also updated to handle both NameStringValuePair objects (typed config path) and raw dicts (YAML path), making the full dict path testable.

Custom exporter example

tracer_provider:
  processors:
    - batch:
        exporter:
          my_custom_exporter: {}
[project.entry-points."opentelemetry_traces_exporter"]
my_custom_exporter = "my_package:MySpanExporterClass"

Remaining work

The OTLP factory functions still use typed attribute access (config.endpoint, etc.) internally. Converting them to accept raw dicts from the YAML loader is tracked in #5127.

Closes #5069

SpanExporter, LogRecordExporter, and PushMetricExporter are changed from
@DataClass to TypeAlias = dict[str, Any] in models.py, preserving unknown
exporter names as dict keys through the config pipeline.

Each signal's factory function (_create_span_exporter, _create_log_record_exporter,
_create_push_metric_exporter) now has a registry of known exporter names
(otlp_http, otlp_grpc, console) with fallback to load_entry_point for
unknown names via the opentelemetry_{traces,logs,metrics}_exporter
entry point groups.

_parse_headers in _common.py is updated to handle both NameStringValuePair
objects (typed config) and raw dicts (YAML path), making the full dict
path testable end-to-end.

Assisted-by: Claude Opus 4.6
The generated models are unchanged. Python dataclasses don't enforce
field types at runtime, so parent fields like BatchSpanProcessor.exporter
naturally accept raw dicts (from the YAML loader) alongside typed
instances. Tests updated to pass raw dicts consistently.

Assisted-by: Claude Opus 4.6
@MikeGoldsmith MikeGoldsmith marked this pull request as draft April 20, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(config): generic plugin loading for OTLP exporters in declarative config

2 participants